package com.bdmc.web.controller.home;

import com.bdmc.alarm.domain.bo.AlarmEventBo;
import com.bdmc.alarm.domain.vo.AlarmEventVo;
import com.bdmc.alarm.service.IAlarmEventService;
import com.bdmc.base.domain.bo.BaseFenceBo;
import com.bdmc.base.domain.vo.BaseFenceVo;
import com.bdmc.base.service.IBaseDeviceService;
import com.bdmc.base.service.IBaseFenceService;
import com.bdmc.common.constant.Constants;
import com.bdmc.common.core.controller.BaseController;
import com.bdmc.common.core.domain.AjaxResult;
import com.bdmc.common.utils.RedisUtils;
import com.bdmc.common.utils.poi.ExcelUtil;
import com.bdmc.device.domain.bo.DevFacilityRealtimeBo;
import com.bdmc.device.domain.bo.DevGpsHistoryBo;
import com.bdmc.device.domain.bo.DevGpsRealtimeBo;
import com.bdmc.device.domain.vo.DevFacilityRealtimeVo;
import com.bdmc.device.domain.vo.DevGpsHistoryVo;
import com.bdmc.device.domain.vo.DevGpsRealtimeVo;
import com.bdmc.device.service.IDevFacilityRealtimeService;
import com.bdmc.device.service.IDevGpsHistoryService;
import com.bdmc.device.service.IDevGpsRealtimeService;
import com.bdmc.device.service.IDevHealthRealtimeService;
import com.bdmc.task.service.ITaskPlanDetailService;
import com.bdmc.web.tcp.TcpClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("/home")
public class HomeController extends BaseController {

    @Autowired
    private IDevGpsRealtimeService gpsRealtimeService;

    @Autowired
    IDevFacilityRealtimeService facRealtimeService;

    @Autowired
    IBaseFenceService fenceService;

    @Autowired
    IAlarmEventService alarmEventService;

    @Autowired
    IDevGpsHistoryService gpsHistoryService;

    @Autowired
    IBaseDeviceService deviceService;

    @Autowired
    ITaskPlanDetailService planDetailService;

    @Autowired
    IDevHealthRealtimeService healthRealtimeService;

    /**
     * 地图页面首次默认加载数据
     *
     * @return map
     */
    @GetMapping("/realtime")
    public AjaxResult<Map<String, Object>> realtime() {
        //只查询在线设备
        DevGpsRealtimeBo devGpsRealtimeBo = new DevGpsRealtimeBo().setOnlineStatus(1);
        Map<String, Object> map = new HashMap<>();
        map.put("person", gpsRealtimeService.selectPersonRealtimeListAll(devGpsRealtimeBo));
        map.put("car", gpsRealtimeService.selectCarRealtimeListAll(devGpsRealtimeBo));
        map.put("fac", facRealtimeService.selectDevFacilityRealtimeList(new DevFacilityRealtimeBo().setOnlineStatus(1)));
        return AjaxResult.success(map);
    }

    /**
     * 地图页面人员数据
     *
     * @param devGpsRealtimeBo 人员查询条件
     * @return 列表
     */
    @GetMapping("/realtime/person")
    public AjaxResult<List<DevGpsRealtimeVo>> realtimePerson(DevGpsRealtimeBo devGpsRealtimeBo) {
        return AjaxResult.success(gpsRealtimeService.selectPersonRealtimeListAll(devGpsRealtimeBo));
    }

    /**
     * 地图页面车辆数据
     *
     * @param devGpsRealtimeBo 车辆查询条件
     * @return 列表
     */
    @GetMapping("/realtime/car")
    public AjaxResult<List<DevGpsRealtimeVo>> realtimeCar(DevGpsRealtimeBo devGpsRealtimeBo) {
        return AjaxResult.success(gpsRealtimeService.selectCarRealtimeListAll(devGpsRealtimeBo));
    }

    /**
     * 地图围栏数据
     *
     * @param facilityRealtime 垃圾桶查询
     * @return 列表
     */
    @GetMapping("/realtime/fac")
    public AjaxResult<List<DevFacilityRealtimeVo>> realtimeFac(DevFacilityRealtimeBo facilityRealtime) {
        return AjaxResult.success(facRealtimeService.selectDevFacilityRealtimeList(facilityRealtime));
    }

    /**
     * 地图围栏数据
     *
     * @param fenceBo 围栏查询
     * @return 列表
     */
    @GetMapping("/realtime/fence")
    public AjaxResult<List<BaseFenceVo>> realtimeFence(BaseFenceBo fenceBo) {
        return AjaxResult.success(fenceService.queryList(fenceBo));
    }

    /**
     * 地图页面右侧看板内容
     *
     * @return
     */
    @GetMapping("/statistic")
    public AjaxResult<Map<String, Object>> statistic(Long deptId) {
        if (deptId == null || deptId == 0) {
            deptId = getDeptId();
        }
        Map<String, Object> map = new HashMap<>();
        List<Map<String, Object>> countHomeWorkPersonList = gpsRealtimeService.countHomeWorkPerson(deptId);
        List<Map<String, Object>> countHomeWorkCarList = gpsRealtimeService.countHomeWorkCar(deptId);
        Map<String, Object> countHomeFacStatusMap = facRealtimeService.countHomeFacStatus();
        Map<String, Object> personOnlineCount = planDetailService.selectWorkPersonOnlineCount(deptId);
        //List<Map<String, Object>> homeFacAlarmCountList = devFacilityHistoryService
        //       .homeFacAlarmCount(new DevFacilityHistory());
        map.put("fac", countHomeFacStatusMap);
        map.put("workPersonCount", personOnlineCount);
        map.put("person", countHomeWorkPersonList);
        map.put("car", countHomeWorkCarList);
        return AjaxResult.success(map);
    }

    /**
     * 地图页面告警数量滚动
     *
     * @return map
     */
    @GetMapping("/alarm")
    public AjaxResult<Map<String, Object>> alarm(Long deptId) {
        Map<String, Object> map = new HashMap<>();
        List<DevFacilityRealtimeVo> realtimeList = facRealtimeService.selectDevFacilityRealtimeList(new DevFacilityRealtimeBo().setOverflow(1));
        List<AlarmEventVo> eventList = alarmEventService.queryList(new AlarmEventBo().setTargetType("person").setDeptId(deptId));
        map.put("facAlarm", realtimeList);
        map.put("personAlarm", eventList);
        return AjaxResult.success(map);
    }

    /**
     * 首页统计数量
     *
     * @return map
     */
    @GetMapping("/count")
    public AjaxResult<Map<String, Object>> count() {
        Map<String, Object> map = new HashMap<>();
        map.put("count", gpsRealtimeService.countHomeAllData());
        return AjaxResult.success(map);
    }


    @GetMapping("/trace")
    public AjaxResult<List<DevGpsHistoryVo>> trace(DevGpsHistoryBo gpsHistoryBo) {
        List<DevGpsHistoryVo> historyVos = gpsHistoryService.traceList(gpsHistoryBo);
        return AjaxResult.success(historyVos);
    }

    @PostMapping("/trace/export")
    public void traceExport(DevGpsHistoryBo gpsHistoryBo, HttpServletResponse response) {
        List<DevGpsHistoryVo> historyVos = gpsHistoryService.traceList(gpsHistoryBo);
        ExcelUtil.exportExcel(historyVos, "轨迹信息", DevGpsHistoryVo.class, response);
    }

    /**
     * 查询设备直播地址
     */
    @GetMapping(value = "/car/video/live")
    public AjaxResult<Void> getVideoAddress(String simCard, String channel) {
        String videoUrlKey = Constants.LBS_VIDEO_WATCHING + simCard + "-" + channel;
        boolean videoUrlExist = RedisUtils.hasKey(videoUrlKey);
        String personKey = Constants.LBS_VIDEO_PERSON + simCard + "-" + channel;
        if (videoUrlExist) {
            String videoUrl = RedisUtils.getCacheObject(videoUrlKey);
            log.info("已存在视频地址:" + videoUrl);
            long count = RedisUtils.increment(personKey);
            log.info(simCard + "-" + channel + "新增视频1个在线，总数量：" + count);
            return AjaxResult.success(videoUrl);
        } else {
            String url = TcpClient.sendVideoLive(simCard, channel);
            // 先缓存视频地址，再缓存新增一个观看人数
            RedisUtils.setCacheObject(videoUrlKey, url, 1200, TimeUnit.SECONDS);
            long count = RedisUtils.increment(personKey);
            log.info(simCard + "-" + channel + "新增视频1个在线，总数量：" + count);
            return AjaxResult.success(url);
        }
    }


    /**
     * 关闭直播地址
     */
    @GetMapping(value = "/car/video/close")
    public AjaxResult<Void> closeVideo(String simCard, String channel) {
        String personKey = Constants.LBS_VIDEO_PERSON + simCard + "-" + channel;
        long count = RedisUtils.decrement(personKey);
        log.info(simCard + "-" + channel + "减少视频1个在线，总数量：" + count);
        if (count == 0) {
            // 关闭设备数据流 并 移除视频链接缓存
            TcpClient.sendVideoLiveStop(simCard, channel);
            RedisUtils.deleteObject(personKey);
            String videoUrlKey = Constants.LBS_VIDEO_WATCHING + simCard + "-" + channel;
            RedisUtils.deleteObject(videoUrlKey);
        }
        return AjaxResult.success();
    }




}
